package com.szjz.excel.importexport.util;
import org.apache.commons.lang3.StringUtils;
import java.text.MessageFormat;
import java.util.Formatter;

/**
 * 字符串格式化工具
 */
public class StringFormatUtil {

    public static void main(String[] args) {
        System.out.println(format("{}{}{}{}", 1, 2, 3));
        System.out.println(MessageFormat.format("{0}{1}{2}{3}", 1, 2, 3));

        Formatter formatter = new Formatter();
        System.out.println(formatter.format("{}{}{}{}", 1, 2, 3));
    }

    /**
     * 示例:<br>
     * 1. formatOrderly(字符串长度应大于{0}小于{1}, 10, 20) --> 字符串长度应大于10小于20<br>
     * 2. formatOrderly(字符串长度应小于{1}, 10, 20) --> 字符串长度应小于20<br>
     *
     * @param pattern
     * @param args
     * @return
     */
    public static String formatOrderly(final String pattern, final Object... args) {
        return MessageFormat.format(pattern, args);
    }

    /**
     * 格式化字符串<br>
     * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
     * 如果想输出 {} 使用 \\转义 { 即可，<br>
     * 如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
     * 例：<br>
     * 通常使用：format("this is {} for {}", "a", "b") =》 this is a for b<br>
     * 转义{}： format("this is \\{} for {}", "a", "b") =》 this is \{} for a<br>
     * 转义\： format("this is \\\\{} for {}", "a", "b") =》 this is \a for b<br>
     *
     * @param pattern 字符串模板
     * @param args    参数列表
     * @return 结果
     */
    public static String format(final String pattern, final Object... args) {
        if (StringUtils.isBlank(pattern) || (args == null || args.length == 0)) {
            return pattern;
        }
        final int strPatternLength = pattern.length();

        // 初始化定义好的长度以获得更好的性能
        StringBuilder sbuf = new StringBuilder(strPatternLength + 50);

        int handledPosition = 0;// 记录已经处理到的位置
        int delimIndex;// 占位符所在位置
        for (int argIndex = 0; argIndex < args.length; argIndex++) {
            delimIndex = pattern.indexOf("{}", handledPosition);
            if (delimIndex == -1) {// 剩余部分无占位符
                if (handledPosition == 0) { // 不带占位符的模板直接返回
                    return pattern;
                } else { // 字符串模板剩余部分不再包含占位符，加入剩余部分后返回结果
                    sbuf.append(pattern, handledPosition, strPatternLength);
                    return sbuf.toString();
                }
            } else {
                if (delimIndex > 0 && pattern.charAt(delimIndex - 1) == '\\') {// 转义符
                    if (delimIndex > 1 && pattern.charAt(delimIndex - 2) == '\\') {// 双转义符
                        // 转义符之前还有一个转义符，占位符依旧有效
                        sbuf.append(pattern, handledPosition, delimIndex - 1);
                        // sbuf.append(StringUtils.utf8Str(argArray[argIndex]));
                        sbuf.append(args[argIndex]);
                        handledPosition = delimIndex + 2;
                    } else {
                        // 占位符被转义
                        argIndex--;
                        sbuf.append(pattern, handledPosition, delimIndex - 1);
                        sbuf.append('{');
                        handledPosition = delimIndex + 1;
                    }
                } else {// 正常占位符
                    sbuf.append(pattern, handledPosition, delimIndex);
                    // sbuf.append(StrUtil.utf8Str(argArray[argIndex]));
                    sbuf.append(args[argIndex]);
                    handledPosition = delimIndex + 2;
                }
            }
        }
        // append the characters following the last {} pair.
        // 加入最后一个占位符后所有的字符
        sbuf.append(pattern, handledPosition, pattern.length());

        return sbuf.toString();
    }
}
